/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.devs.benchmark;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.devs.benchmark.modeling.ModelType;
import javax.xml.bind.*;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import org.devs.benchmark.dot.DevsToDot;
import org.devs.benchmark.modeling.CoupledType;
import org.devs.benchmark.modeling.ObjectFactory;
import org.devs.benchmark.topology.Network;
import org.devs.benchmark.topology.TridMesh;

/**
 *
 * @author Alejandro Moreno
 */
public class Main {

    public static void toXML(ModelType model, String url) {

        try {

            JAXBContext jaxbContext = JAXBContext.newInstance("org.devs.benchmark.modeling");
            Marshaller marshaller = jaxbContext.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true));
            ObjectFactory factory = new ObjectFactory();
            marshaller.marshal(factory.createModel(model), new FileOutputStream(url));

        } catch (FileNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (JAXBException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void toDot(ModelType model, String url) {

        BufferedWriter out = null;

        try {
            out = new BufferedWriter(new FileWriter(url));
            out.write(DevsToDot.DevsModelToDot(model));

        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

    public static void toGraph(String dotUrl, String format, String outputName){
            
            String s = null;

        try {


            Process p = Runtime.getRuntime().exec("dot "+dotUrl+" -T"+format+" -o "+outputName);

            BufferedReader stdInput = new BufferedReader(new
                 InputStreamReader(p.getInputStream()));
            
            BufferedReader stdError = new BufferedReader(new
                 InputStreamReader(p.getErrorStream()));


            while ((s = stdInput.readLine()) != null) {
                System.out.println(s);
            }


            while ((s = stdError.readLine()) != null) {
                System.out.println(s);
            }

        }
        catch (IOException e) {

            e.printStackTrace();

        }
    }


    public static void getSchema(String url){
        try {
            final File baseDir = new File(".");
            final String urlName = url;
            class MySchemaOutputResolver extends SchemaOutputResolver {

                public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
                    if(urlName!=null)
                        return new StreamResult(new File(urlName));
                    else
                        return new StreamResult(new File(baseDir, suggestedFileName));
                }
            }
            JAXBContext context = JAXBContext.newInstance(CoupledType.class, Job.class);
            context.generateSchema(new MySchemaOutputResolver());
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (JAXBException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void main(String[] args) throws Exception {
        

        /*Network line = new Line("Line", 3, Job.class,1);
        line.mgToDot("line.dot");
        toGraph("line.dot", "png", "line.png");
        line.toXML("line.xml");

        Network lineD = new Line("LineD", 3, Job.class,3);
        lineD.mgToDot("lineD.dot");
        toGraph("lineD.dot", "png", "lineD.png");
        lineD.toXML("lineD.xml");
        

        Network ring = new CordonalRing("Ring", 8,2, Job.class,1);
        ring.mgToDot("ring.dot");
        toGraph("ring.dot", "png", "ring.png");
        ring.toXML("ring.xml");

        
        Network complete = new CordonalRing("Complete", 8,7, Job.class,1);
        complete.mgToDot("complete.dot");
        toGraph("complete.dot", "png", "complete.png");
        complete.toXML("complete.xml");
        
        
        Network cRing = new CordonalRing("cRing", 8,5, Job.class,1);
        cRing.mgToDot("cRing.dot");
        toGraph("cRing.dot", "png", "cRing.png");
        cRing.toXML("cRing.xml");


        Network cDRing = new CordonalRing("cDRing", 6,3, Job.class,3);
        cDRing.mgToDot("cDRing.dot");
        toGraph("cDRing.dot", "png", "cDRing.png");
        cDRing.toXML("cDRing.xml");
        

        
        Network star = new Star("star", 8,Job.class,1);
        star.mgToDot("star.dot");
        toGraph("star.dot", "png", "star.png");
        star.toXML("star.xml");

        Network starD = new Star("star", 3,Job.class,3);
        starD.mgToDot("starD.dot");
        toGraph("starD.dot", "png", "starD.png");
        starD.toXML("starD.xml");

        
        Network tree = new Tree("tree", 3,3,Job.class,2);
        tree.mgToDot("tree.dot");
        toGraph("tree.dot", "png", "tree.png");
        tree.toXML("tree.xml");

        
        Network fatTree = new FatTree("fatTree", 2,4,Job.class);
        fatTree.mgToDot("fatTree.dot");
        toGraph("fatTree.dot", "png", "fatTree.png");
        fatTree.toXML("fatTree.xml");

        Network cmesh = new ClosedMesh("cmesh", 3,3,Job.class,1);
        cmesh.mgToDot("cmesh.dot");
        toGraph("cmesh.dot", "png", "cmesh.png");
        cmesh.toXML("cmesh.xml");


        Network hcube = new NKCube("hcube", 3,2,Job.class,1);
        hcube.buildModel();
        hcube.mgToDot("hcube.dot");
        toGraph("hcube.dot", "png", "hcube.png");
        hcube.toXML("hcube.xml");*/

        Network triMesh = new TridMesh("triMesh", 2,2,2,Job.class,1);
        triMesh.buildModel();
        triMesh.mgToDot("triMesh.dot");
        toGraph("triMesh.dot", "png", "triMesh.png");
        triMesh.toXML("triMesh.xml");

        //Network network = new Ring("Ring", 5,3);
        //Network network = new CordonalRing("Ring", 8,5,Job.class,1);
        //Network network = new Mesh("Mesh", 3,2,Job.class,1);
        //Network network = new Systolic("Systolic", 3,3,2);
        //Network network = new Star("Star", 5,3);

        //getSchema("schema.xsd");

    }
}

